package main

import (
	"encoding/json"
	"fmt"
	"github.com/astaxie/beego"
	"github.com/hyperledger/fabric-sdk-go/pkg/client/channel"
	"github.com/hyperledger/fabric-sdk-go/pkg/core/config"
	"github.com/hyperledger/fabric-sdk-go/pkg/fabsdk"
	"log"
)

const (
	org1CfgPath = "./config.yaml"
	ChannelID   = "mychannel"

	peer0Org1 = "peer0.org1.puTaolian.com"
)
type InvokeController struct {
	beego.Controller
}
type QueryController struct {
	beego.Controller
}
var cc *channel.Client

type RequestBody_Obj struct {
	ChaincodeID string `json:"chaincodeID"`            // 注意首字母大写
	Fnc   string `json:"fnc"`
	Args []string `json:"args"`
}
type ResponseBody_Obj struct {
	TxID string `json:"txID"`            // 交易ID
	Code int32 `json:"code"`//     正常返回200异常返回500
	Payload string `json:"payload"` //查询结果
	ErrMsg string `json:"errMsg"`
}
func (this *InvokeController) Post() {
	this.EnableRender=false //关闭flt
	var requestBody RequestBody_Obj
	body := this.Ctx.Input.RequestBody
	json.Unmarshal(body, &requestBody)
	resp:=execute(requestBody.ChaincodeID,requestBody.Fnc,requestBody.Args,cc)
	this.Data["json"]= resp
	this.ServeJSON()
}
func (this *QueryController) Post() {
	this.EnableRender=false //关闭flt 停止渲染
	var requestBody RequestBody_Obj
	body := this.Ctx.Input.RequestBody
	json.Unmarshal(body, &requestBody)
	resp:=query(requestBody.ChaincodeID,requestBody.Fnc,requestBody.Args,cc)
	this.Data["json"]= resp
	this.ServeJSON()
}
func main() {
	sdk, err := fabsdk.New(config.FromFile(org1CfgPath))
	if err != nil {
		log.Panicf("failed to create fabric sdk: %s", err)
	}

	ccp := sdk.ChannelContext(ChannelID, fabsdk.WithUser("User1"))
	cc, err = channel.New(ccp)
	if err != nil {
		log.Panicf("failed to create channel client: %s", err)
	}
	beego.Router("/sdk/invoke", &InvokeController{})
	beego.Router("/sdk/query", &QueryController{})
	beego.Run()
}
func query(chainCodeID string,fcn string,args []string,cc *channel.Client) ResponseBody_Obj{
	// new channel request for query
	req := channel.Request{
		ChaincodeID: chainCodeID,  //116 114 测试tps
		Fcn:         fcn, //116 114 测试tps
		Args:        packArgs(args),
	}
	// send request and handle response
	reqPeers := channel.WithTargetEndpoints(peer0Org1)
	response, err := cc.Query(req, reqPeers)
	var responseBody ResponseBody_Obj
	code:=response.ChaincodeStatus
	txId:=response.TransactionID
	responseBody.TxID=string(txId);
	responseBody.Payload=string(response.Payload)
	if code!=200 {
		responseBody.Code=500
	}else {
		responseBody.Code=code
	}
	var errMsg string
	if err != nil {
		errMsg=fmt.Sprintf("failed to query chaincode: %s\n", err)
	}
	responseBody.ErrMsg=errMsg
	return  responseBody;
}

func execute(chainCodeID string,fcn string,args []string,cc *channel.Client) ResponseBody_Obj{
	req := channel.Request{
		ChaincodeID: chainCodeID,//116 114 测试tps
		Fcn:         fcn, //116  114测试tpst
		Args:        packArgs(args),
	}
	peers := []string{peer0Org1}
	reqPeers := channel.WithTargetEndpoints(peers...)
	response, err := cc.Execute(req, reqPeers)
	var responseBody ResponseBody_Obj
	code:=response.ChaincodeStatus
	txId:=response.TransactionID
	responseBody.TxID=string(txId);
	if code!=200 {
		responseBody.Code=500
	}else {
		responseBody.Code=code
	}
	var errMsg string
	if err != nil {
		errMsg=fmt.Sprintf("failed to Execute chaincode: %s\n", err)
	}
	responseBody.ErrMsg=errMsg
	return  responseBody
}

func packArgs(paras []string) [][]byte {
	var args [][]byte
	for _, k := range paras {
		args = append(args, []byte(k))
	}
	return args
}
